package org.xiaobai.ai.fakeopen.timer;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.Header;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.xiaobai.ai.api.enums.ApiTypeEnum;
import org.xiaobai.core.config.ChatConfig;
import org.xiaobai.core.utils.OkHttpClientUtil;
import org.xiaobai.core.utils.RedisUtil;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;

/**
 * @author dingfeng.xiao
 * @description 定时刷新token
 * @date 2023/12/11 14:07
 */
@RestController
@RequestMapping("/timer")
@EnableScheduling
@Slf4j
@Service
public class RefreshTokenUtil {
    @Resource
    private ChatConfig chatConfig;
    @Resource
    private RedisUtil redisUtil;
    public String getAccessToken(String username, String password) throws IOException {
        OkHttpClient okHttpClient = OkHttpClientUtil.getInstance(ApiTypeEnum.FAKE_OPEN_TOKEN, 60000, 60000, 60000, null);
        RequestBody formBody = new FormBody.Builder()
                .add("username", username)
                .add("password", password)
                .build();
        // 构建请求头
        Headers headers = new Headers.Builder()
                .add(Header.CONTENT_TYPE.name(), ContentType.FORM_URLENCODED.getValue())
                .build();
        Request request = new Request.Builder()
                .url(chatConfig.getFakeOpenProxy() + "/api/auth/login")
                .post(formBody)
                .headers(headers)
                .build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.body() != null) {
                final FakeOpenResponse fakeOpenResponse = JSON.parseObject(response.body().string(), FakeOpenResponse.class);
                redisUtil.set("fakeopen_login_result", JSON.toJSONString(fakeOpenResponse));
                return fakeOpenResponse.getAccess_token();
            }
        }
        return null;
    }

    public String getShareToken(String accessToken) throws IOException {
        OkHttpClient okHttpClient = OkHttpClientUtil.getInstance(ApiTypeEnum.FAKE_OPEN_TOKEN, 60000, 60000, 60000, null);
        RequestBody formBody = new FormBody.Builder()
                .add("unique_name", "xiaodfuname")
                .add("access_token", accessToken)
                .add("expires_in", "0")
                .build();
        // 构建请求头
        Headers headers = new Headers.Builder()
                .add(Header.CONTENT_TYPE.name(), ContentType.FORM_URLENCODED.getValue())
                .build();
        Request request = new Request.Builder()
                .url(chatConfig.getFakeOpenProxy() + "/api/token/register")
                .post(formBody)
                .headers(headers)
                .build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.body() != null) {
                return JSON.parseObject(response.body().string(), FakeOpenResponse.class).getToken_key();
            }
        }
        return null;
    }
    @GetMapping("/refreshToken")
    @Scheduled(cron = "0 0 0 * * MON")
    @PostConstruct
    public void refreshToken() throws IOException {
        try {
            if (StrUtil.isEmpty(chatConfig.getOpenaiApiKey()) && StrUtil.isNotEmpty(chatConfig.getFakeOpenProxy())) {
                String accesstoken = this.getAccessToken(chatConfig.getOpenaiUserName(), chatConfig.getOpenaiPassword());
                String sk = this.getShareToken(accesstoken);
                if (StrUtil.isEmpty(sk)) {
                    log.info("获取sk为空");
                    return;
                }
                redisUtil.set("fakeopen_accessionToken", sk);
                chatConfig.setOpenaiAccessToken(sk);
                log.info("refreshToken： " + chatConfig.getOpenaiAccessToken());
            }
        } catch (Exception e) {
            log.error("refreshToken error: " , e);
            String accessionToken = redisUtil.get("fakeopen_accessionToken");
            if (StrUtil.isNotEmpty(accessionToken)) {
                chatConfig.setOpenaiAccessToken(accessionToken);
            }
        }
    }
}
